package com.shuma.userservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shuma.common.utils.IpUtils;
import com.shuma.userservice.mq.LogMessageSender;
import com.shuma.common.event.OperationLogEvent;
import com.shuma.common.exception.BadRequestException;
import com.shuma.userservice.config.JwtProperties;
import com.shuma.userservice.domain.dto.LoginDTO;
import com.shuma.userservice.domain.dto.RegisterDTO;
import com.shuma.userservice.domain.dto.ResetPasswordDTO;
import com.shuma.userservice.domain.dto.UpdateUserDTO;
import com.shuma.userservice.domain.pojo.Users;
import com.shuma.userservice.domain.vo.UserLoginVO;
import com.shuma.userservice.query.PageQuery;
import com.shuma.userservice.service.UsersService;
import com.shuma.userservice.mapper.UsersMapper;
import com.shuma.userservice.utils.JwtTool;
import com.shuma.common.utils.UserContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.shuma.userservice.feign.PermissionFeignClient;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
* @author 86189
* @description 针对表【users】的数据库操作Service实现
* @createDate 2025-06-13 15:24:18
*/
@Service
@RequiredArgsConstructor
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users>
    implements UsersService {

    private final PermissionFeignClient permissionFeignClient;
    private final UsersMapper usersMapper;
    private final JwtTool jwtTool;
    private final JwtProperties jwtProperties;
    private final LogMessageSender logMessageSender;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void register(RegisterDTO dto) {
            List<Users> users = usersMapper.selectList(new QueryWrapper<Users>().eq("username", dto.getUsername()));
            if(users.size() > 0) {
                throw new IllegalArgumentException("用户名 '" + dto.getUsername() + "' 已存在");
            }
            // 创建用户对象
            Users user = new Users();
            user.setUserId(IdWorker.getId());
            user.setUsername(dto.getUsername());
            user.setPassword(dto.getPassword());
            user.setEmail(dto.getEmail());
            user.setPhone(dto.getPhone());
            user.setGmtCreate(new Date());
            // 保存用户
            usersMapper.insert(user);

            // 2. RPC 调用权限服务绑定默认角色
            permissionFeignClient.bindDefaultRole(user.getUserId());

            //TODO MQ
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String ip = IpUtils.getClientIp(request);
            OperationLogEvent event = new OperationLogEvent();
            event.setUserId(user.getUserId());
            event.setAction("register");
            event.setIp(ip);
            event.setDetail("注册新用户: " + user.getUserId());
            logMessageSender.send(event);
        }




    @Override
    public UserLoginVO login(LoginDTO dto) {
        // 1. 数据校验（非空，视需求可增强）
        String username = dto.getUsername();
        String password = dto.getPassword();
        // 2. 根据用户名查询用户（你可以改成手机号或其他条件）
        Users user = lambdaQuery().eq(Users::getUsername, username).one();
        if (user == null) {
            throw new BadRequestException("用户名错误");
        }
        // 3. 校验密码
        if (!password.equals(user.getPassword())) {
            throw new BadRequestException("密码错误");
        }
        // 4. 生成 JWT token
        String token = jwtTool.createToken(user.getUserId(), jwtProperties.getTokenTTL());
        // 5. 封装返回对象
        UserLoginVO vo = new UserLoginVO();
        vo.setUserId(user.getUserId());
        vo.setUsername(user.getUsername());
        vo.setToken(token);

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpUtils.getClientIp(request);
        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(user.getUserId());
        event.setAction("login");
        event.setIp(ip);
        event.setDetail("用户"+user.getUserId()+"登录");
        logMessageSender.send(event);

        return vo;
    }

    @Override
    public Page<Users> getUsersByPage(PageQuery query) {
        Long currentUserId = UserContext.getUserId();
        String userRoleCode = permissionFeignClient.getUserRoleCode(currentUserId);
        // 构建分页对象，默认按 gmt_create 倒序
        Page<Users> page = query.toMpPageDefaultSortByCreateTimeDesc();

        LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();

        // 根据角色过滤数据
        if ("user".equals(userRoleCode)) {
            // 普通用户只能看自己
            wrapper.eq(Users::getUserId, currentUserId);
        } else if ("admin".equals(userRoleCode)) {
            // 管理员看所有普通用户（role_code = 'user' 的用户）
            // 这里假设 Users 表里没有直接 role_code，需要联表查询
            // MyBatis-Plus 不支持直接 join，需自己写 SQL 或用子查询实现
            List<Long> userIds = permissionFeignClient.getUserIdsByRole("user");
            // 假设 Users 表有 user_id，且角色绑定在 user_roles 表，可以用 exists 子查询
            wrapper.in(Users::getUserId, userIds);
        } else if ("super_admin".equals(userRoleCode)) {

        } else {
            // 其他角色，默认只能看自己
            wrapper.eq(Users::getUserId, currentUserId);
        }
        // 额外的筛选条件示例：用户名模糊搜索
        // if (StrUtil.isNotBlank(query.getUsername())) {
        //     wrapper.like(Users::getUsername, query.getUsername());
        // }
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpUtils.getClientIp(request);
        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(currentUserId);
        event.setAction("query_user_list");
        event.setIp(ip);
        event.setDetail("用户"+currentUserId+"分页查询用户列表");
        logMessageSender.send(event);

        return this.page(page, wrapper);
    }

    @Override
    public Users getUser(Long userId) {
        Long currentUserId = UserContext.getUserId();
        String currentRoleCode = permissionFeignClient.getUserRoleCode(currentUserId);
        Users user = null;
        if ("super_admin".equals(currentRoleCode)) {
            user = usersMapper.selectOne(new QueryWrapper<Users>().eq("user_id", userId));
            if (user == null) {
                throw new BadRequestException("用户不存在");
            }
        } else if ("admin".equals(currentRoleCode)) {
            String targetRole = permissionFeignClient.getUserRoleCode(userId);
            if ("user".equals(targetRole)) {
                user = usersMapper.selectOne(new QueryWrapper<Users>().eq("user_id", userId));
            } else {
                throw new RuntimeException("该用户不存在或者无权限访问该用户信息");
            }
        } else {
            if (currentUserId.equals(userId)) {
                user = usersMapper.selectOne(new QueryWrapper<Users>().eq("user_id", userId));
            } else {
                throw new RuntimeException("该用户不存在或者无权限访问该用户信息");
            }
        }
        if (user == null) {
            throw new BadRequestException("用户不存在");
        }
        // ✅ 发送操作日志
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpUtils.getClientIp(request);

        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(currentUserId);
        event.setAction("query_user_detail");
        event.setIp(ip);
        event.setDetail(currentUserId+"查询用户信息，目标用户ID: " + userId);

        logMessageSender.send(event);
        return user;
    }

    @Override
    public Users resetPassword(ResetPasswordDTO dto) {
        Long currentUserId = UserContext.getUserId();
        String currentRole = permissionFeignClient.getUserRoleCode(currentUserId);
        Long targetUserId = dto.getUserId();

        if ("super_admin".equals(currentRole)) {
            // 超管可以改任何人
        } else if ("admin".equals(currentRole)) {
            String targetRole = permissionFeignClient.getUserRoleCode(targetUserId);
            if (!"user".equals(targetRole)) {
                throw new RuntimeException("管理员只能重置普通用户密码");
            }
        } else {
            // 普通用户只能改自己
            if (!currentUserId.equals(targetUserId)) {
                throw new RuntimeException("无权限重置该用户密码");
            }
        }
        // 执行更新
        Users user=usersMapper.selectOne(new  QueryWrapper<Users>().eq("user_id", targetUserId));
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        user.setPassword(dto.getNewPassword());
        usersMapper.update(user, new UpdateWrapper<Users>().eq("user_id", targetUserId));
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpUtils.getClientIp(request);
        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(currentUserId);
        event.setAction("reset_password");
        event.setIp(ip);
        event.setDetail(currentUserId+"重置用户密码: targetUserId=" + targetUserId);
        logMessageSender.send(event);

        return user;
    }

    @Override
    public Users updateUser(Long targetUserId, UpdateUserDTO dto) {
        Long currentUserId = UserContext.getUserId();
        String currentRole = permissionFeignClient.getUserRoleCode(currentUserId);

        if ("super_admin".equals(currentRole)) {
            // 超管可以修改所有人，无限制
        } else if ("admin".equals(currentRole)) {
            String targetRole = permissionFeignClient.getUserRoleCode(targetUserId);
            if (!"user".equals(targetRole)) {
                throw new RuntimeException("管理员只能修改普通用户的信息");
            }
        } else {
            // 普通用户只能改自己
            if (!currentUserId.equals(targetUserId)) {
                throw new RuntimeException("无权限修改其他用户信息");
            }
        }

        Users user=usersMapper.selectOne(new  QueryWrapper<Users>().eq("user_id", targetUserId));
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        // 修改字段 构建日志
        StringBuilder detailBuilder = new StringBuilder("{");
        if (dto.getPhone() != null) {
            detailBuilder.append("\"field\":\"phone\",\"old\":\"").append(user.getPhone()).append("\",\"new\":\"").append(dto.getPhone()).append("\"");
            user.setPhone(dto.getPhone());
        }
        if (dto.getEmail() != null) {
            if (detailBuilder.length() > 1) detailBuilder.append(", ");
            detailBuilder.append("\"field\":\"email\",\"old\":\"").append(user.getEmail()).append("\",\"new\":\"").append(dto.getEmail()).append("\"");
            user.setEmail(dto.getEmail());
        }
        detailBuilder.append("}");
        // 其他字段同理
        usersMapper.update(user, new UpdateWrapper<Users>().eq("user_id", targetUserId));

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = IpUtils.getClientIp(request);
        OperationLogEvent event = new OperationLogEvent();
        event.setUserId(currentUserId);
        event.setAction("update_user");
        event.setIp(ip);
        event.setDetail(currentUserId+"修改"+targetUserId+"的信息 具体为"+detailBuilder.toString());
        logMessageSender.send(event);

        return user;
    }
}




